//
//  ViewController.m
//  Homework_25
//
//  Created by 徐昊 on 16/8/17.
//  Copyright © 2016年 徐昊. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;


@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
//    [ViewController sharedViewController];
//    [self chapterOfGCD];
    [self loadImage];
    [self asyncGroupNotify];
}
#pragma mark - 知识点: GCD


#pragma mark ** GCD 应用场景 - 单例
+ (instancetype)sharedViewController {
    
    static ViewController *vc = nil;
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        vc = [[ViewController alloc] init];
    });
    
    return vc;
}
#pragma mark ** GCD 应用场景 - 图片异步下载
- (void)loadImage {
    
    // 在子线程运行下载图片代码.
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        NSURL *url = [NSURL URLWithString:@"http://img5.cache.netease.com/3g/2015/10/30/20151030124521c1f7e.jpg"];
        
        NSData *data = [NSData dataWithContentsOfURL:url];
        
        // 返回主线程, UI赋值
        dispatch_async(dispatch_get_main_queue(), ^{
            
            self.imageView.image = [UIImage imageWithData:data];
            
        });
    });
    
    
    
    
    
}
#pragma mark ** GCD 创建
- (void)chapterOfGCD {
    
#if 0
    // 创建串行队列.
    dispatch_queue_t queue = dispatch_queue_create("com.lanou3g", DISPATCH_QUEUE_SERIAL);
    
    dispatch_async(queue, ^{
        
        [self snippet];
        
    });
    dispatch_async(queue, ^{
        
        NSLog(@"ddd");
        
    });
#endif
    
    // 创建并发队列.
    dispatch_queue_t queue = dispatch_queue_create("dls160710.lanou3g", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(queue, ^{
        [NSThread sleepForTimeInterval:6];
        NSLog(@"aaaa");
        
    });
    dispatch_async(queue, ^{
        
        NSLog(@"ddd");
        
    });
    
}
#pragma mark - dispatch group
-(void)asyncGroupNotify
{
    NSLog(@"star");
    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_queue_create("com.GCD_demo.www", DISPATCH_QUEUE_CONCURRENT);
    dispatch_group_async(group, queue, ^{
        [NSThread sleepForTimeInterval:1];
        NSLog(@"group_work_1");
    });
    dispatch_group_async(group, queue, ^{
        [NSThread sleepForTimeInterval:6];
        NSLog(@"group_work_2");
    });
    dispatch_group_async(group, queue, ^{
        [NSThread sleepForTimeInterval:2];
        NSLog(@"group_work_3");
    });
    
    dispatch_group_notify(group, queue, ^{
        NSLog(@"dispatch_group_Notify 结束");
    });
}
#pragma mark - depatch_group_wait
// dispatchgroup在
-(void)asyncGroupWait
{
    NSLog(@"star");
    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_queue_create("com.GCD_demo.www", DISPATCH_QUEUE_CONCURRENT);
    dispatch_group_async(group, queue, ^{
        [NSThread sleepForTimeInterval:1];
        NSLog(@"group_work_1");
    });
    dispatch_group_async(group, queue, ^{
        [NSThread sleepForTimeInterval:6];
        NSLog(@"group_work_2");
    });
    dispatch_group_async(group, queue, ^{
        [NSThread sleepForTimeInterval:2];
        NSLog(@"group_work_3");
    });
    
    //在此设置了一个12秒的等待时间，如果group的执行结束没有到12秒那么就返回0
    //如果执行group的执行时间超过了12秒，那么返回非0 数值，
    //在使用dispatch_group_wait函数的时候，会阻塞当前线程，阻塞的时间 在wait函数时间值和当前group执行时间值取最小的。
    long kk = dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, 12 * NSEC_PER_SEC));
    if(kk == 0)
    {
        NSLog(@"dispatch_group_wait 结果1");
    }
    else
    {
        NSLog(@"dispatch_group_wait 结果2");
    }
    
}

#pragma mark - dispatch_apply
// 类似一个for循环,会在指定的dispatch queue中运行block任务n次，如果队列是并发队列，则会并发执行block任务，dispatch_apply是一个同步调用，block任务执行n次后才返回。
-(void)dispatchApply
{
    dispatch_queue_t queue = dispatch_queue_create("com.GCD_demo.www", DISPATCH_QUEUE_CONCURRENT);
    
    
    dispatch_apply(6, queue, ^(size_t i) {
        NSLog(@"do a job %zu times",i);
        
    });
    NSLog(@"go on");
}
#pragma mark - dispatch_barrier_async
// 使用 dispatch_barrier_async 开辟的队列要等到前面的任务都执行完后才能执行, 同样的在他后面的队列也要等到他完全执行完毕之后才能进行
-(void)diapatchBarrier
{
    dispatch_queue_t queue = dispatch_queue_create("com.GCD_demo.www", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(queue, ^{
        [NSThread sleepForTimeInterval:6];
        NSLog(@"dispatch_async_work1");
    });
    dispatch_async(queue, ^{
        [NSThread sleepForTimeInterval:2];
        NSLog(@"dispatch_async_work2");
    });
    dispatch_barrier_async(queue, ^{
        NSLog(@"dispatch_async_work3");
        [NSThread sleepForTimeInterval:1];
        
    });
    dispatch_async(queue, ^{
        [NSThread sleepForTimeInterval:1];
        NSLog(@"dispatch_async_work4");
    });
}
#pragma mark - dispatch_set_target_queue
// 在创建新队列的时候, 我们可以指定队列的优先级
-(void)DispatchSet
{
    dispatch_queue_t serialDiapatchQueue = dispatch_queue_create("com.GCD_demo.www", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t dispatchgetglobalqueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
    dispatch_set_target_queue(serialDiapatchQueue, dispatchgetglobalqueue);
    dispatch_async(serialDiapatchQueue, ^{
        NSLog(@"我优先级低，先让让");
    });
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"我优先级高,我先block");
    });
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
@end
